#关于装饰器
'''
1.不需要传递参数，两层闭包
2.需要传递参数，3层闭包
3.如果是对象装饰器，必须要用————call————方法

'''


def upper(method):
    new_args = []
    new_kwargs = {}

    def inner(*args, **kwargs):
        for a in args:
            if a == 'name':
                raise KeyError

            if isinstance(a, str):
                new_args.append(a.upper())
            else:
                new_args.append(a)

        for key, value in kwargs.items():
            if key == 'name':
                raise KeyError
            if isinstance(value, str):
                new_kwargs[key] = value.upper()
            else:
                new_kwargs[key] = value

        return method(*new_args, **new_kwargs)

    return inner


class Upper:
    def __init__(self, method):
        self.method = method

    def __call__(self, *args, **kwargs):
        new_args = []
        new_kwargs = {}

        for a in args:
            if a == 'name':
                raise KeyError

            if isinstance(a, str):
                new_args.append(a.upper())
            else:
                new_args.append(a)

        for key, value in kwargs.items():
            if key == 'name':
                raise KeyError
            if isinstance(value, str):
                new_kwargs[key] = value.upper()
            else:
                new_kwargs[key] = value

        return self.method(*new_args, **new_kwargs)

def argument(**keyarg):
    new_kwargs = {}

    def outer(method):
        def inner(**kwargs):
            for key, value in keyarg.items():
                new_key = key.split('__')[0]
                key_style = key.split('__')[1]
                if new_key not in kwargs.keys() and value == 1:
                    raise Exception('can not find {}'.format(new_key))
                for k, v in kwargs.items():
                    if new_key == k:
                        # if key_style == 'int':
                        #
                        #     new_kwargs[k] = int(v)
                        # else:
                        #     new_kwargs[k] = v
                        new_kwargs[k] = eval(key_style)(v)  #eval函数，直接根据类型强转
                    else:
                        new_kwargs[k] = v

            return method(**new_kwargs)
        return inner
    return outer


@argument(username__str=1,age__int=1,gender__int=0)
def func(**kwargs):
    print(kwargs)


func(username='ww',age='2',gender='1',abc='adc')
